from django.views import View
from django.http import JsonResponse
from django_redis import get_redis_connection
import re
import random

from user import user_constants as u_const
from meiduo_move_server import project_constants as p_const
from user.utils.sms_utils import SendSmsVerificationCode
from meiduo_move_server.utils import request_utils as req_utils
from meiduo_move_server.utils import data_type_change_utils
from user.utils import user_account_utils
from meiduo_move_server.utils.mysql_utils import MySQLUtils
from user.utils import jwt_utils


# Create your views here.
class Register(View):
    """
    处理用户注册请求的视图类
    """

    def get(self, req):
        """
        get方法用于处理用户注册时获取短信验证码的请求
        @param - req: 请求对象
        @return: 返回本次请求对应的响应对象
        """
        userTelephone = req.GET.get('userTelephone')  # 获取用户手机号
        userTelephoneIsOK = re.search(u_const.USER_TELEPHONE_REGULAR, userTelephone)  # 判断传递过来的手机号格式是否正确
        if userTelephoneIsOK is None:  # 如果用户的手机号格式有误
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '手机号格式有误'
            })
        try:
            redis_conn = get_redis_connection('user')  # 获取Redis用户数据库连接
            sms_mark = redis_conn.get('sms_mark_%s' % userTelephone)  # 获取用户对应的短信验证码的标记，用于判断当前是否可以再次发送短信验证码
        except Exception as e:
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'massage': 'Redis数据库连接出错'
            })
        if sms_mark is not None:  # 如果获取的短信验证码标记不为空，则不允许再次发送短信验证码
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '请勿频繁请求发送短信验证码'
            })
        if u_const.SMS_VERIFICATION_IS_OPEN:  # 如果开启短信验证码功能
            smsVerificationCode = '%06d' % random.randint(0, 999999)  # 生成短信验证码
            res = SendSmsVerificationCode().send_message(  # 发送短信验证码
                mobile='%s' % userTelephone,
                datas=(smsVerificationCode, u_const.SMS_VERIFICATION_CODE_VALID_TIME // 60),
                tid=1
            )
            if res != '000000':  # 如果短信验证码发送失败
                return JsonResponse({
                    'mark': p_const.MARK_ERROR,
                    'message': '短信验证码发送失败'
                })
        else:  # 没有开启短信验证码功能
            smsVerificationCode = u_const.SMS_VERIFICATION_FIXED  # 使用固定的短信验证码
        try:
            pl = redis_conn.pipeline()  # 通过连接对象获取pipeline对象
            pl.set('sms_code_%s' % userTelephone, smsVerificationCode,
                   u_const.SMS_VERIFICATION_CODE_VALID_TIME)  # Redis数据库中保存短信验证码并设置有效时间
            pl.set('sms_mark_%s' % userTelephone, smsVerificationCode,
                   u_const.SMS_VERIFICATION_CODE_SEND_AGAIN_WAIT_TIME)  # 保存用户对应的短信验证码的标记，用于判断是否可以再次发送短信验证码
            pl.execute()  # 执行短信验证码保存到redis数据库语句
        except Exception as e:
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'massage': 'Redis数据库出现错误'
            })
        # 短信验证码发送成功保存成功
        return JsonResponse({
            'mark': p_const.MARK_SUCCESS,
            'message': '短信验证码发送成功'
        })

    def post(self, req):
        """
        post方法用于处理用户注册请求
        @param - req: 请求对象
        @return: 返回本次请求对应的响应对象
        """
        req_data = req_utils.getPostDataToDict(req.body)  # 得到post发送过来的数据转化为字典类型
        userTelephone = req_data.get('userTelephone')  # 获取用户手机号
        userTelephoneIsOK = re.search(u_const.USER_TELEPHONE_REGULAR, userTelephone)  # 判断传递过来的手机号格式是否正确
        if userTelephoneIsOK is None:  # 如果用户的手机号格式有误
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '手机号格式有误'
            })
        sms_code_redis = None
        try:
            redis_conn = get_redis_connection("user")  # 获取redis数据库连接对象
            sms_code_redis = redis_conn.get("sms_code_%s" % userTelephone)  # 从redis数据库获取短信验证码
        except Exception as e:
            # print('Redis数据库获取短信验证码出现错误')
            # print(e)
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '短信验证码对比出错，请重新发送注册请求'
            })
        sms_code_redis = data_type_change_utils.bin2str(sms_code_redis)  # 获取字符串类型的短信验证码
        if sms_code_redis is None:
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '短信验证码已失效，请重新申请发送短信验证码'
            })
        smsVerificationCode = req_data.get('smsVerificationCode')  # 获取用户输入的短信验证码
        if smsVerificationCode != sms_code_redis:  # 如果短信验证码输入错误
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '短信验证码输入错误，请重新输入'
            })
        # 至此验证成功，进行用户账号的生成
        userAccountData = user_account_utils.createUserAccount(userTelephone)  # 用户账号和注册时间
        userAccount = userAccountData['userAccount']  # 用户账号
        userRegisterTimeStr = user_account_utils.getUserAccountRegisterTimeStr(
            userAccountData['userRegisterTime'])  # 字符串类型用户账号注册时间
        userPassword = req_data.get('userPassword')
        # 用户账号信息和用户个人信息入数据库
        sql = """
        INSERT INTO user_account_info(user_account, user_telephone, user_password, user_register_time)
        VALUES (%s, %s, %s, %s);
        """
        res = MySQLUtils.update(sql, (userAccount, userTelephone, userPassword, userRegisterTimeStr))
        if res < 1:
            return JsonResponse({
                'mark': p_const.MARK_ERROR,
                'message': '账号写入数据库失败，请重新提交注册请求'
            })
        return JsonResponse({
            'mark': p_const.MARK_SUCCESS,
            'message': '账号注册成功'
        })






